package de.hs_fulda.SoftComputing.Gogol.Wasserkraft;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.util.HashMap;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class PresentationController {
  private JSlider strombedarf;
  private JSlider pegelZufluss;
  private JSlider pegelstandAblass;
  private JSlider pegelStausee;
  private JLabel labelPegelZufluss;
  private JLabel labelStaudamm;
  private JLabel labelWater;
  private JLabel labelWaterShape;
  
  private JLabel labelPegelStausee;
  private JLabel labelPegelAblass;
  private JLabel labelStrombedarf;
  //private JProgressBar progressSchleuseTurbine;
  //private JProgressBar progressSchleuseAblass;
  private JProgressBar progressPegelZufluss;
  private JProgressBar progressBelastung;
  private JPanel panelBecken;
  private JPanel panelTurbine;
  private JPanel panelAblass;
  private JPanel panelAbfluss;
  
  private JPanel panelSchleuseTurbine;
  private JPanel panelSchleuseAbfluss;
  
  private VarPanel panelVarOutput;
  private VarPanel panelVarInput;
  
  private JPanel newContentPane = new JPanel(true);
  private WasserkraftFuzzyController fuzzy;
  
  private HashMap<INPUT, String> toolTipsInput;
  private HashMap<OUTPUT, String> toolTipsOutput;
  
  private Color water = new Color(0, 43, 167);
  private Color schleuse = new Color(66, 38, 9);
  
  private int schleusePixel;
  public PresentationController (Container contentPane, WasserkraftFuzzyController fuzzy) {
    this.fuzzy = fuzzy;
    newContentPane.setOpaque(true); 
    newContentPane.setLayout(null);
    contentPane.add(newContentPane);
    toolTipsInput = new HashMap<INPUT, String>() {/**
       * 
       */
      private static final long serialVersionUID = 1L;

    {
      put(INPUT.PegelAblass, 
	  "<html>rot  =  niedrig<br/>" +
	  "gr&uuml;n = normal<br/>" +
	  "blau = hoch<br/>" +
          "gelb = kritisch</html>");
      put(INPUT.PegelZufluss, 
	  "<html>rot  =  niedrig<br/>" +
	  "gr&uuml;n = normal<br/>" +
	  "blau = hoch<br/>" +
          "gelb = kritisch</html>");
      put(INPUT.PegelStausee, 
	  "<html>gelb =  unterEntnahme<br/>" +
	  "rot  = eisernerVorrat<br/>" +
	  "gr&uuml;n = bewirtschSpeicher<br/>" +
          "blau = ausserstesStauziel</html>");
      put(INPUT.Strombedarf, 
	  "<html>blau =  keiner<br/>" +
	  "rot  = niedrig<br/>" +
	  "gr&uuml;n = hoch</html>");
    }};
    toolTipsOutput = new HashMap<OUTPUT, String>(){/**
       * 
       */
      private static final long serialVersionUID = 1L;

    {
      put(OUTPUT.Belastungsanzeige, 
	  "<html>rot  =  niedrig<br/>" +
	  "gr&uuml;n = normal<br/>" +
	  "blau = hoch<br/>" +
          "gelb = kritisch</html>");
      
      put(OUTPUT.SchleusenAblass, 
	  "<html>rot  =  auf<br/>" +
	  "blau = zu</html>");
      put(OUTPUT.SchleusenTurbine, 
	  "<html>rot  =  auf<br/>" +
	  "blau = zu</html>");
    }};
  }
  public void createGui() {
    createSlider();
    createLabels();
    createProgressBars();
    createSchleusen();
    createWater();
    createVarPanels();
    updateOutput();
  }
  private void updateWater () {
    int stausee = pegelStausee.getValue();
    int abfluss = pegelstandAblass.getValue();
    int newY = 40 + (int)(165*((100 - stausee)/100.0));
    int newYAbfluss = 182 + (int)(80*((15 - abfluss)/15.0));
    int yAblass;
    
    panelBecken.setBounds(25, newY, 284, (int) (165 * (stausee/100.0)));	 
    
    if (newY > 155) {
      yAblass = 155;
    } else if (newY < 139){
      yAblass = 139;
    } else {
      yAblass = newY;
    }
    double schleuse = fuzzy.getOutputVariable(OUTPUT.SchleusenTurbine);
    if (schleuse < 100.0) {
      yAblass = (int) (139 + Math.round((100-schleuse)/100.0 * 16.0));
    }
    panelTurbine.setBounds(305, yAblass, 308, 155 - yAblass);
    
    if (newY > 182) {
      yAblass = 182;
    } else if (newY < 169){
      yAblass = 169;
    } else {
      yAblass = newY;
    }
    schleuse = fuzzy.getOutputVariable(OUTPUT.SchleusenAblass);
    if (schleuse < 100.0) {
      yAblass = (int) (169 + Math.round((100-schleuse)/100.0 * 13.5));
    }
    panelAblass.setBounds(305, yAblass, 327, 182 - yAblass);
    
    panelAbfluss.setBounds(605, newYAbfluss, 177, 262 - newYAbfluss);
    if (schleusePixel >= 12)
    {
      if (labelWater.isVisible())
      {
	labelWater.setVisible(false);
      }
    }
    else
    {
      if (!labelWater.isVisible())
      {
	labelWater.setVisible(true);
      }
      labelWaterShape.setBounds(612-schleusePixel, 125+schleusePixel, 100, 120);
    }
  }
  private void updateSchleusen () {
    int ablass =  100 - (int) Math.round(fuzzy.getOutputVariable(OUTPUT.SchleusenAblass));
    int turbine = 100 - (int) Math.round(fuzzy.getOutputVariable(OUTPUT.SchleusenTurbine));
    int hoehe;
 
    hoehe = (int) (((double)turbine/100.0 * 13.0) + 3.0);
    schleusePixel = hoehe-3;
    panelSchleuseTurbine.setBounds(308, 138, 5, hoehe);
    
    hoehe = (int) (((double)ablass/100.0 * 11.0) + 3.0);
    panelSchleuseAbfluss.setBounds(308, 167, 5, hoehe);           
  }
  private void createVarPanels () {
    panelVarInput = new VarPanel();
    newContentPane.add(panelVarInput);
    panelVarInput.setBounds(10, 280, 780, 120);
    panelVarInput.setEnabled(true);
    for (INPUT input: INPUT.values()) {
      panelVarInput.addPicture(fuzzy.getInputChart(input), toolTipsInput.get(input));
    }
    
    panelVarOutput = new VarPanel();
    newContentPane.add(panelVarOutput);
    panelVarOutput.setBounds(200, 410, 600, 150);
    panelVarOutput.setEnabled(true);
    for (OUTPUT output: OUTPUT.values()) {
      panelVarOutput.addPicture(fuzzy.getOutputChart(output), toolTipsOutput.get(output));
    }
  }
  private void createSchleusen () {
    panelSchleuseTurbine = new JPanel();
    newContentPane.add(panelSchleuseTurbine);
    panelSchleuseTurbine.setBounds(308, 138, 5, 3);
    panelSchleuseTurbine.setBackground(schleuse);
    panelSchleuseTurbine.setEnabled(true);
  	
    panelSchleuseAbfluss = new JPanel();
    newContentPane.add(panelSchleuseAbfluss);
    panelSchleuseAbfluss.setBounds(308, 167, 5, 3);
    panelSchleuseAbfluss.setBackground(schleuse);
    panelSchleuseAbfluss.setEnabled(true);
  }
  private void createWater() {
    // TODO Auto-generated method stub
    {
	panelBecken = new JPanel();
	newContentPane.add(panelBecken);
	panelBecken.setBounds(25, 40, 284, 165);
	panelBecken.setBackground(water);
	panelBecken.setEnabled(true);
    }
    {
      	panelTurbine = new JPanel();
      	newContentPane.add(panelTurbine);
      	panelTurbine.setBounds(305, 140, 308, 15);
      	panelTurbine.setBackground(water);
      	panelBecken.setEnabled(true);
    }
    {
	panelAblass = new JPanel();
      	newContentPane.add(panelAblass);
      	panelAblass.setBounds(305, 168, 327, 15);
      	panelAblass.setBackground(water);
      	panelAblass.setEnabled(true);
    }

  }
  private void createProgressBars() {
    {
	progressBelastung = new JProgressBar(SwingConstants.HORIZONTAL);
	newContentPane.add(progressBelastung);
	progressBelastung.setBounds(460, 25, 200, 25);
    }
    {
	progressPegelZufluss = new JProgressBar(SwingConstants.VERTICAL, 0, 15);
	newContentPane.add(progressPegelZufluss);
	progressPegelZufluss.setBounds(10, 70, 20, 150);
	progressPegelZufluss.setForeground(new Color(0, 0, 255));
	progressPegelZufluss.setValue(pegelZufluss.getValue());
    }
  }
  private void createLabels() {
    // TODO Auto-generated method stub
    {
	JLabel labelBelastung = new JLabel();
	newContentPane.add(labelBelastung);
	labelBelastung.setText("Belastungsanzeige");
	labelBelastung.setBounds(460, 8, 195, 15);
	labelBelastung.setFont(new Font(null, Font.BOLD, 16));
    }
    {
	JLabel labelNiedrig = new JLabel();
	newContentPane.add(labelNiedrig);
	labelNiedrig.setText("niedrig");
	labelNiedrig.setBounds(405, 28, 50, 15);
	labelNiedrig.setFont(new Font(null, Font.PLAIN, 12));	
    }
    {
	JLabel labelHoch = new JLabel();
	newContentPane.add(labelHoch);
	labelHoch.setText("hoch");
	labelHoch.setBounds(665, 28, 195, 15);
	labelHoch.setFont(new Font(null, Font.PLAIN, 12));	
    }
    {
	labelStrombedarf = new JLabel();
	newContentPane.add(labelStrombedarf);
	labelStrombedarf.setText("Strombedarf");
	labelStrombedarf.setBounds(50, 415, 150, 20);
	labelStrombedarf.setHorizontalAlignment(SwingConstants.LEFT);
	labelStrombedarf.setHorizontalTextPosition(SwingConstants.LEFT);
	labelStrombedarf.setVerticalAlignment(SwingConstants.TOP);
	labelStrombedarf.setVerticalTextPosition(SwingConstants.TOP);
    }
    
    {
	labelPegelZufluss = new JLabel();
	newContentPane.add(labelPegelZufluss);
	labelPegelZufluss.setText("Pegel Zufluss");
	labelPegelZufluss.setBounds(50, 465, 150, 15);
    }
    {
	labelPegelAblass = new JLabel();
	newContentPane.add(labelPegelAblass);
	labelPegelAblass.setText("Pegel Ablass");
	labelPegelAblass.setBounds(50, 515, 150, 15);
    }
    {
	labelPegelStausee = new JLabel();
	newContentPane.add(labelPegelStausee);
	labelPegelStausee.setText("Pegel Stausee");
	labelPegelStausee.setBounds(50, 565, 150, 15);
    }
    {
	labelStaudamm = new JLabel();
	newContentPane.add(labelStaudamm);
	labelStaudamm.setIcon(new ImageIcon(getClass().getClassLoader().getResource("de/hs_fulda/SoftComputing/Gogol/Wasserkraft/res/Staudamm.png")));
	labelStaudamm.setBounds(0, 0, 800, 600);
	labelStaudamm.setOpaque(false);
	labelStaudamm.setEnabled(true);
    }
    {
      panelAbfluss = new JPanel();
  	newContentPane.add(panelAbfluss);
  	panelAbfluss.setBounds(605, 180, 177, 80);
  	panelAbfluss.setBackground(water);
  	panelAbfluss.setEnabled(true);
    }
    {
	labelWaterShape= new JLabel();
	newContentPane.add(labelWaterShape);
	labelWaterShape.setIcon(new ImageIcon(getClass().getClassLoader().getResource("de/hs_fulda/SoftComputing/Gogol/Wasserkraft/res/water_shape.png")));
	labelWaterShape.setBounds(612, 125, 100, 120);
	labelWaterShape.setOpaque(false);
	labelWaterShape.setEnabled(true);
    }
    
    {
	labelWater = new JLabel();
	newContentPane.add(labelWater);
	labelWater.setIcon(new ImageIcon(getClass().getClassLoader().getResource("de/hs_fulda/SoftComputing/Gogol/Wasserkraft/res/water.png")));
	labelWater.setBounds(612, 125, 75, 120);
	labelWater.setOpaque(false);
	labelWater.setEnabled(true);
    }
    	    
  }
  private void createSlider() {
    // TODO Auto-generated method stub
    {
	pegelStausee = new JSlider(0, 100, 80);
	newContentPane.add(pegelStausee);
	pegelStausee.setBounds(10, 580, 200, 16);
	fuzzy.setInputVariable(INPUT.PegelStausee, 80);
	pegelStausee.addChangeListener(new ChangeListener() {
	  public void stateChanged(ChangeEvent evt) {	   
	    fuzzy.setInputVariable(INPUT.PegelStausee, pegelStausee.getValue());	    
	    updateOutput();
	  }
	});
    }
    {
	pegelstandAblass = new JSlider(0, 15, 7);
	newContentPane.add(pegelstandAblass);
	fuzzy.setInputVariable(INPUT.PegelAblass, 7);
	pegelstandAblass.setBounds(10, 530, 200, 16);
	pegelstandAblass.addChangeListener(new ChangeListener() {
	  public void stateChanged(ChangeEvent evt) {
	    fuzzy.setInputVariable(INPUT.PegelAblass, ((JSlider)evt.getSource()).getValue());
	    updateOutput();
	  }
	});
    }
    {
	pegelZufluss = new JSlider(0,15, 5);
	newContentPane.add(pegelZufluss);
	pegelZufluss.setBounds(10, 480, 202, 16);
	fuzzy.setInputVariable(INPUT.PegelZufluss, 5);
	pegelZufluss.addChangeListener(new ChangeListener() {
	  public void stateChanged(ChangeEvent evt) {
	    int value = ((JSlider)evt.getSource()).getValue();
	    fuzzy.setInputVariable(INPUT.PegelZufluss, value);
	    progressPegelZufluss.setValue(value);
	    updateOutput();
	  }
	});
    }
    {
	strombedarf = new JSlider(0, 100, 80);
	newContentPane.add(strombedarf);
	strombedarf.setBounds(10, 430, 200, 16);
	fuzzy.setInputVariable(INPUT.Strombedarf, 80);
	strombedarf.addChangeListener(new ChangeListener() {
	  public void stateChanged(ChangeEvent evt) {
	    fuzzy.setInputVariable(INPUT.Strombedarf, ((JSlider)evt.getSource()).getValue());
	    updateOutput();
	  }
	});
    }
  }
  private void updateOutput () {
    updateSchleusen();
    updateProgressBars();
    updateWater();
    updateVars();
    newContentPane.repaint();
  }
  private void updateVars() {
    int i = 0;
    /* Input */
    for (INPUT input : INPUT.values()) {
      panelVarInput.updatePicture(fuzzy.getInputChart(input), i++);
    }
    i = 0;
    /* Output */
    for (OUTPUT output : OUTPUT.values()) {
      panelVarOutput.updatePicture(fuzzy.getOutputChart(output), i++);
    }
  }
  private void updateProgressBars() {
    int value;
    value = (int) Math.round(fuzzy.getOutputVariable(OUTPUT.Belastungsanzeige));
    progressBelastung.setValue(value);
    value = (int) Math.round(fuzzy.getOutputVariable(OUTPUT.SchleusenAblass));    
    //progressSchleuseAblass.setValue(value);
    value = (int) Math.round(fuzzy.getOutputVariable(OUTPUT.SchleusenTurbine));    
    //progressSchleuseTurbine.setValue(value);    
  }
}
